#include "MappingNodeHandler.h"
#include "assert.h"
#include <map>

MappingNodeHandler* MappingNodeHandler::_selector=NULL;

MappingNodeHandler::MappingNodeHandler(){
	
	xMappingNodeTypeLibrary *lib=xMappingNodeTypeLibrary::getInstance();
	this->_node_number=lib->get_xmnt_no();
	for(int i=0;i<lib->get_xmnt_no();i++){
		this->addNode(lib->get_xmnt_descriptor(i));
	}
	
}

MappingNodeHandler* MappingNodeHandler::getInstance(){

	if(_selector==NULL){
		_selector=new MappingNodeHandler();
	}
	return _selector;

}

void MappingNodeHandler::addNode(xMappingNodeTypeDescriptor *des){
	
	assert(des);
	
	if(des->_hidden==true)
		return ;
	addCategory(des->_category);

	auto itr = _node_map.find(des->_category);
	if ( itr!= _node_map.end()){
		itr->second.push_back(des);
	} else {
		this->_node_map[des->_category].push_back(des);
	}
	
	//this->_node_map[des->_category].push_back(des);
}

void MappingNodeHandler::addCategory(std::string category){

	assert(!category.empty());

	auto itr=this->_node_categorys.begin();
	for(;itr!=this->_node_categorys.end();itr++){
		if( (*itr) ==category){
			return ;
		}
	}
	this->_node_categorys.push_back(category);

}

void MappingNodeHandler::refreshNodeList(){
	
	xMappingNodeTypeLibrary *lib=xMappingNodeTypeLibrary::getInstance();

	if(this->_node_number<lib->get_xmnt_no()){
		this->addNode(lib->get_xmnt_descriptor(this->_node_number++));
	}
}

std::vector<xMappingNodeTypeDescriptor*>* MappingNodeHandler::getNodeList( const std::string category ) {
	
	auto itr = _node_map.find(category);

	if ( _node_map.end() != itr ){
		return &(itr->second);
	}
	// TODO throw an exception
	assert( !"invalid category" );
	return NULL;
}

std::vector<xMappingNodeTypeDescriptor*>* MappingNodeHandler::getNodeList( const int index ) {

	std::string category=this->_node_categorys[index];
	return this->getNodeList(category);	
}
std::vector<std::string>* MappingNodeHandler::getCategorys(){
	
	return &(this->_node_categorys);
}

void MappingNodeHandler::saveVMToLibrary( std::string name,std::string type,std::string des,xMappingTree* xmt ){

	xMappingNodeTypeLibrary *lib=xMappingNodeTypeLibrary::getInstance();
	lib->add_compositevm_from_xMappingTree(name,type,des,xmt);

	this->refreshNodeList();

}

void MappingNodeHandler::deleteVMFromLibrary( std::string name )
{
	xMappingNodeTypeLibrary *lib=xMappingNodeTypeLibrary::getInstance();
	lib->delete_vm_from_xmnt_library(name);

	this->refreshNodeList();
}
